﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace config.service
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;

        /// <summary>
        /// FFB协议解析器 - 处理接收的字节流，解析成协议帧，并触发相应事件
        /// </summary>
    public class FFBProtocolParser: IFFBProtocol
    {
        #region 常量定义
        public const ushort PROTOCOL_HEADER = 0xAA55;
        public const int MAX_FRAME_SIZE = 71; // 最大帧长度
        public const int MIN_FRAME_SIZE = 5;  // 最小帧长度(头2+命令1+长度1+校验1)

        private readonly byte[] _headerBytes = { 0x55, 0xAA }; // 小端序
        #endregion

        #region 枚举定义
        public enum FFBCommand : byte
        {
            CMD_RESET_DEVICE = 0x01,
            CMD_GET_DEVICE_INFO = 0x02,
            CMD_DEVICE_INFO_RESP = 0x03,
            CMD_SAVE_PARAMS = 0x04,
            CMD_OPERATION_RESULT = 0x05,
            CMD_GET_ALL_PARAMS = 0x10,
            CMD_PARAMS_RESP = 0x11,
            CMD_SET_SPRING_PARAMS = 0x12,
            CMD_SET_DAMPER_PARAMS = 0x13,
            CMD_SET_INERTIA_PARAMS = 0x14,
            CMD_SET_FRICTION_PARAMS = 0x15,
            CMD_SET_WHEEL_CENTER = 0x16,
            CMD_PLAY_TEST_EFFECT = 0x30,
            CMD_STOP_ALL_EFFECTS = 0x31,
            CMD_REALTIME_FORCE = 0x32,
            CMD_EFFECT_STATUS = 0x33,
            CMD_ENABLE_DATA_STREAM = 0x50,
            CMD_DISABLE_DATA_STREAM = 0x51,
            CMD_POSITION_DATA = 0x52,
            CMD_FORCE_OUTPUT_DATA = 0x53,
            CMD_DEVICE_STATUS = 0x54
        }

        public enum FFBErrorCode : byte
        {
            ERR_SUCCESS = 0x00,
            ERR_INVALID_CMD = 0x01,
            ERR_INVALID_DATA = 0x02,
            ERR_DEVICE_BUSY = 0x03,
            ERR_FLASH_WRITE = 0x04
        }

        [Flags]
        public enum DataStreamType : byte
        {
            DATA_STREAM_NONE = 0,
            DATA_STREAM_POSITION = 1,
            DATA_STREAM_FORCE = 2,
            DATA_STREAM_STATUS = 4,
            DATA_STREAM_ALL = 7
        }
        #endregion

        #region 数据结构
        public class ProtocolFrame
        {
            public ushort Header { get; set; }
            public FFBCommand Command { get; set; }
            public byte DataLength { get; set; }
            public byte[] Data { get; set; } = new byte[64];
            public byte Checksum { get; set; }

            public bool IsValid { get; set; }
            public string ErrorMessage { get; set; }
        }

        public class DeviceInfo
        {
            public byte[] FwVersion { get; set; } = new byte[4];
            public ushort DeviceId { get; set; }
            public byte HardwareRev { get; set; }
            public uint SerialNumber { get; set; }
            public ushort MaxForce { get; set; }
            public byte AxisCount { get; set; }

            public string FirmwareVersionString => $"{FwVersion[0]}.{FwVersion[1]}.{FwVersion[2]}.{FwVersion[3]}";
        }
        #endregion

        #region 事件定义
        public event Action<ProtocolFrame> OnFrameReceived;
        public event Action<DeviceInfo> OnDeviceInfoReceived;
        public event Action<FFBErrorCode> OnOperationResult;
        public event Action<string> OnError;
        #endregion

        #region 解析状态
        private readonly List<byte> _receiveBuffer = new List<byte>();
        private bool _frameStarted = false;
        private int _searchIndex = 0;
        #endregion

        /// <summary>
        /// 处理接收到的内存流数据
        /// </summary>
        /// <param name="stream">内存流数据</param>
        public void ProcessStreamData(MemoryStream stream)
        {
            if (stream == null || stream.Length == 0)
                return;

            byte[] data = stream.ToArray();
            ProcessByteData(data, 0, (int)stream.Length);
        }

        /// <summary>
        /// 处理字节数组数据
        /// </summary>
        /// <param name="data">字节数组</param>
        /// <param name="offset">偏移量</param>
        /// <param name="length">数据长度</param>
        public void ProcessByteData(byte[] data, int offset, int length)
        {
            for (int i = offset; i < offset + length; i++)
            {
                ProcessSingleByte(data[i]);
            }
        }

        /// <summary>
        /// 处理单个字节（状态机方式）
        /// </summary>
        private void ProcessSingleByte(byte dataByte)
        {
            if (!_frameStarted)
            {
                // 寻找帧头
                if (_searchIndex == 0 && dataByte == _headerBytes[0])
                {
                    _receiveBuffer.Add(dataByte);
                    _searchIndex = 1;
                }
                else if (_searchIndex == 1 && dataByte == _headerBytes[1])
                {
                    _receiveBuffer.Add(dataByte);
                    _frameStarted = true;
                    _searchIndex = 0;
                }
                else
                {
                    // 重置搜索状态
                    _searchIndex = 0;
                    if (_receiveBuffer.Count > 0)
                        _receiveBuffer.Clear();
                }
            }
            else
            {
                // 接收帧数据
                _receiveBuffer.Add(dataByte);

                // 检查是否收到足够数据来解析基本帧信息
                if (_receiveBuffer.Count >= 4) // 头2 + 命令1 + 长度1
                {
                    byte dataLength = _receiveBuffer[3];
                    int totalFrameLength = 4 + dataLength + 1; // header(2)+command(1)+length(1)+data(n)+checksum(1)

                    // 检查是否收到完整帧
                    if (_receiveBuffer.Count >= totalFrameLength)
                    {
                        ParseCompleteFrame(totalFrameLength);
                    }
                }

                // 防止缓冲区溢出
                if (_receiveBuffer.Count >= MAX_FRAME_SIZE)
                {
                    ResetParserState("缓冲区溢出");
                }
            }
        }

        /// <summary>
        /// 解析完整帧
        /// </summary>
        private void ParseCompleteFrame(int frameLength)
        {
            try
            {
                byte[] frameData = _receiveBuffer.Take(frameLength).ToArray();
                ProtocolFrame frame = ParseFrame(frameData);

                if (frame.IsValid)
                {
                    OnFrameReceived?.Invoke(frame);
                    HandleSpecificCommand(frame);
                }
                else
                {
                    OnError?.Invoke(frame.ErrorMessage);
                }

                // 移除已处理的数据
                _receiveBuffer.RemoveRange(0, frameLength);
                _frameStarted = false;

                // 检查缓冲区是否还有数据需要处理（粘包情况）
                if (_receiveBuffer.Count >= 2)
                {
                    CheckForNextFrame();
                }
            }
            catch (Exception ex)
            {
                ResetParserState($"解析帧时发生异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 检查是否有下一帧数据
        /// </summary>
        private void CheckForNextFrame()
        {
            // 在剩余数据中查找帧头
            for (int i = 0; i <= _receiveBuffer.Count - 2; i++)
            {
                if (_receiveBuffer[i] == _headerBytes[0] && _receiveBuffer[i + 1] == _headerBytes[1])
                {
                    // 找到新的帧头，移动数据到缓冲区开头
                    if (i > 0)
                    {
                        List<byte> newBuffer = _receiveBuffer.Skip(i).ToList();
                        _receiveBuffer.Clear();
                        _receiveBuffer.AddRange(newBuffer);
                        _frameStarted = true;
                    }
                    return;
                }
            }

            // 没有找到有效帧头，清空缓冲区
            _receiveBuffer.Clear();
        }

        /// <summary>
        /// 解析帧数据
        /// </summary>
        private ProtocolFrame ParseFrame(byte[] frameData)
        {
            var frame = new ProtocolFrame();

            try
            {
                using (var ms = new MemoryStream(frameData))
                using (var reader = new BinaryReader(ms))
                {
                    frame.Header = reader.ReadUInt16();
                    frame.Command = (FFBCommand)reader.ReadByte();
                    frame.DataLength = reader.ReadByte();

                    if (frame.DataLength > 0)
                    {
                        frame.Data = reader.ReadBytes(frame.DataLength);
                    }

                    frame.Checksum = reader.ReadByte();
                }

                // 验证校验和
                byte calculatedChecksum = CalculateChecksum(frameData, 2, frame.DataLength + 2); // 从command开始计算
                if (frame.Checksum != calculatedChecksum)
                {
                    frame.IsValid = false;
                    frame.ErrorMessage = $"校验和错误: 期望0x{calculatedChecksum:X2}, 实际0x{frame.Checksum:X2}";
                    return frame;
                }

                frame.IsValid = true;
                return frame;
            }
            catch (Exception ex)
            {
                frame.IsValid = false;
                frame.ErrorMessage = $"帧解析异常: {ex.Message}";
                return frame;
            }
        }

        /// <summary>
        /// 计算校验和
        /// </summary>
        public static byte  CalculateChecksum(byte[] data, int startIndex, int length)
        {
            byte sum = 0;
            for (int i = startIndex; i < startIndex + length && i < data.Length; i++)
            {
                sum += data[i];
            }
            return sum;
        }

        /// <summary>
        /// 处理特定命令
        /// </summary>
        private void HandleSpecificCommand(ProtocolFrame frame)
        {
            switch (frame.Command)
            {
                case FFBCommand.CMD_DEVICE_INFO_RESP:
                    HandleDeviceInfo(frame.Data, frame.DataLength);
                    break;

                case FFBCommand.CMD_OPERATION_RESULT:
                    HandleOperationResult(frame.Data, frame.DataLength);
                    break;

                case FFBCommand.CMD_POSITION_DATA:
                    // 处理位置数据流

                    break;

                case FFBCommand.CMD_FORCE_OUTPUT_DATA:
                    // 处理力输出数据流
                    break;

                default:
                    // 其他命令通过OnFrameReceived事件处理
                    break;
            }
        }

        /// <summary>
        /// 处理设备信息
        /// </summary>
        private void HandleDeviceInfo(byte[] data, int length)
        {
            if (length >= 13) // 设备信息结构体最小长度
            {
                try
                {
                    var deviceInfo = new DeviceInfo();
                    using (var ms = new MemoryStream(data))
                    using (var reader = new BinaryReader(ms))
                    {
                        deviceInfo.FwVersion = reader.ReadBytes(4);
                        deviceInfo.DeviceId = reader.ReadUInt16();
                        deviceInfo.HardwareRev = reader.ReadByte();
                        deviceInfo.SerialNumber = reader.ReadUInt32();
                        deviceInfo.MaxForce = reader.ReadUInt16();
                        deviceInfo.AxisCount = reader.ReadByte();
                    }

                    OnDeviceInfoReceived?.Invoke(deviceInfo);
                }
                catch (Exception ex)
                {
                    OnError?.Invoke($"解析设备信息失败: {ex.Message}");
                }
            }
        }

        /// <summary>
        /// 处理操作结果
        /// </summary>
        private void HandleOperationResult(byte[] data, int length)
        {
            if (length >= 1)
            {
                var result = (FFBErrorCode)data[0];
                OnOperationResult?.Invoke(result);
            }
        }

        /// <summary>
        /// 重置解析器状态
        /// </summary>
        private void ResetParserState(string errorMessage = null)
        {
            if (!string.IsNullOrEmpty(errorMessage))
            {
                OnError?.Invoke(errorMessage);
            }

            _receiveBuffer.Clear();
            _frameStarted = false;
            _searchIndex = 0;
        }

        /// <summary>
        /// 清空缓冲区并重置状态
        /// </summary>
        public void ClearBuffer()
        {
            ResetParserState();
        }

        /// <summary>
        /// 创建命令帧（用于发送）
        /// </summary>
        public static byte[] CreateCommandFrame(FFBCommand command, byte[] data = null)
        {
            using (var ms = new MemoryStream())
            using (var writer = new BinaryWriter(ms))
            {
                // 写入帧头
                writer.Write(PROTOCOL_HEADER);

                // 写入命令和长度
                writer.Write((byte)command);
                byte dataLength = (byte)(data?.Length ?? 0);
                writer.Write(dataLength);

                // 写入数据
                if (dataLength > 0)
                {
                    writer.Write(data, 0, dataLength);
                }

                // 计算并写入校验和
                byte[] frameData = ms.ToArray();
                byte checksum = CalculateChecksum(frameData, 2, dataLength + 2);
                writer.Write(checksum);

                return ms.ToArray();
            }
        }
    }

}
